package com.timkj.wxtemplatemessage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.timkj.wxtemplatemessage.dao.SendByTaskidDao;
import com.timkj.wxtemplatemessage.dto.SendByOpenidDto;
import com.timkj.wxtemplatemessage.dto.SendByTaskidDto;
import com.timkj.wxtemplatemessage.dto.SendMassDto;
import com.timkj.wxtemplatemessage.entity.*;
import com.timkj.wxtemplatemessage.service.BasicService;
import com.timkj.wxtemplatemessage.service.WxTemplateMessageService;
import com.timkj.wxtemplatemessage.utils.ResultVoUtil;
import com.timkj.wxtemplatemessage.utils.log.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Objects;

/**
 * @author : liji
 * @date : 2020-08-25 15:31
 */
@Slf4j
@Service
public class WxTemplateMessageServiceImpl extends BasicService implements WxTemplateMessageService {
    private SendByTaskidDao sendByTaskidDao;

    @Autowired
    public WxTemplateMessageServiceImpl(SendByTaskidDao sendByTaskidDao) {
        this.sendByTaskidDao = sendByTaskidDao;
    }

    /**
     * 群发模板消息
     * @param dto SendMassDto
     */
    @Override
    public ArrayList<ResultVo> sendMass(String accessToken,SendMassDto dto) {
        LogUtil.save(LogUtil.info(this.getClass().getName(),String.valueOf(dto)));
        log.info(String.valueOf(dto));
        ArrayList<String> openidList = getUserList(accessToken);
        ArrayList<ResultVo> resultVos = new ArrayList<>();
        SendByOpenidDto dto1 = new SendByOpenidDto();
        dto1.setAppId(dto.getAppId());
        dto1.setAppSecret(dto.getAppSecret());
        SendMessageEntity entity  = new SendMessageEntity();
        entity.setTemplate_id(dto.getTemplate_id());
        entity.setUrl(dto.getUrl());
        entity.setData(dto.getData());
        for (String openid : openidList){
            entity.setTouser(openid);
            ArrayList<SendMessageEntity> sendMessageEntities = new ArrayList<>();
            sendMessageEntities.add(entity);
            dto1.setMsgData(sendMessageEntities);
            ArrayList<ResultVo> resultVos1 = sendByOpenid(accessToken,dto1);
            ResultVo resultVo  = resultVos1.get(0);
            resultVos.add(resultVo);
        }
        return resultVos;
    }

    /**
     * 通过openid发送模板消息
     * @param dto SendByOpenidDto
     */
    @Override
    public ArrayList<ResultVo> sendByOpenid(String accessToken,SendByOpenidDto dto) {
        LogUtil.save(LogUtil.info(this.getClass().getName(),String.valueOf(dto)));
        log.info(String.valueOf(dto));
        ArrayList<ResultVo> resultVos = new ArrayList<>();
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
        RestTemplate restTemplate = new RestTemplate();
        for (SendMessageEntity entity : dto.getMsgData()){
            ResultVoUtil resultVoUtil = new ResultVoUtil();
            ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url,entity, JSONObject.class);
            if (Objects.requireNonNull(responseEntity.getBody()).getInteger("errcode") == 40001) {
                accessToken = getAccessToken(dto.getAppId(),dto.getAppSecret());
                url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
                responseEntity = restTemplate.postForEntity(url,entity, JSONObject.class);
                insertToken(accessToken);
            }
            ResultVo resultVo = resultVoUtil.success(responseEntity.getBody());
            resultVo.setOpenid(entity.getTouser());
            resultVos.add(resultVo);
        }
        return resultVos;
    }

    /**
     * 通过任务id发送模板消息
     * @param accessToken 微信token
     * @param dto 任务id
     */
    @Override
    public ArrayList<ResultVo> sendByTaskid(String accessToken, SendByTaskidDto dto) {
        LogUtil.save(LogUtil.info(this.getClass().getName(),String.valueOf(dto)));
        log.info(String.valueOf(dto));
        ArrayList<FaMsgEntity> entities = sendByTaskidDao.SelectFaMsgByTaskid(dto.getTaskId());
        SendByOpenidDto dto1 = new SendByOpenidDto();
        dto1.setAppId(dto.getAppId());
        dto1.setAppSecret(dto.getAppSecret());
        ArrayList<ResultVo> resultVos = new ArrayList<>();
        if (entities.size()!=0){
            for (FaMsgEntity entity : entities){
                if ("创建".equals(entity.getStatus()) && "modemsg".equals(entity.getType())){
                    SendMessageEntity sendMessageEntity = new SendMessageEntity();
                    String basicTemplateId = "VBZdZZk7r88a7pLAL2dYUYpieQ05Jy4YBIqxQWXxARc";
                    if (entity.getTemplate_id()!=null){
                        sendMessageEntity.setTemplate_id(entity.getTemplate_id());
                    }else {
                        sendMessageEntity.setTemplate_id(basicTemplateId);
                    }
                    sendMessageEntity.setData(getSendMessageEntityData(entity));
                    sendMessageEntity.setUrl(entity.getUrl());
                    ArrayList<FaMsgItemEntity> faMsgEntities = sendByTaskidDao.SelectFaMsgItemByTaskid(dto.getTaskId());
                    int i=0;
                    for (FaMsgItemEntity entity1 : faMsgEntities){
                        i++;
                        if (i%1000==0){
                            try {
                                LogUtil.save(LogUtil.info(this.getClass().getName(),Thread.currentThread().getName() + "-线程休眠一分钟"));
                                log.info(Thread.currentThread().getName() + "-线程休眠一分钟");
                                Thread.sleep(60000);
                                LogUtil.save(LogUtil.info(this.getClass().getName(),Thread.currentThread().getName() + "-线程休眠结束"));
                                log.info(Thread.currentThread().getName() + "-线程休眠结束");
                            } catch (InterruptedException e) {
                                LogUtil.save(LogUtil.info(this.getClass().getName(),e.getMessage()));
                                log.info(e.getMessage());
                                e.printStackTrace();
                            }
                        }
                        sendMessageEntity.setTouser(entity1.getV_info());
                        ArrayList<SendMessageEntity> sendMessageEntities = new ArrayList<>();
                        sendMessageEntities.add(sendMessageEntity);
                        dto1.setMsgData(sendMessageEntities);
                        ArrayList<ResultVo> resultVos1 = sendByOpenid(accessToken,dto1);
                        ResultVo resultVo = resultVos1.get(0);
                        JSONObject jsonObject = (JSONObject) resultVo.getData();
                        if (jsonObject.getInteger("errcode")==0){
                            entity1.setIsSuccess("送达");
                            sendByTaskidDao.UpdataIsSuccess(entity1);
                        }else {
                            entity1.setResult(String.valueOf(jsonObject));
                            sendByTaskidDao.UpdataResult(entity1);
                        }
                        resultVos.add(resultVo);
                    }
                    entity.setStatus("完成");
                    sendByTaskidDao.UpdataStatus(entity);
                }
            }
        }
        return resultVos;
    }

    /**
     * 获取token
     */
    @Override
    public String getToken(String appId, String appSecret){
        WxTemplateMessageTokenEntity oldToken = sendByTaskidDao.SelectAccessToken();
        String accessToken;
        if (oldToken!=null){
            if (System.currentTimeMillis() < oldToken.getOut_time()){
                accessToken = oldToken.getAccess_token();
            }else {
                accessToken = getAccessToken(appId,appSecret);
                insertToken(accessToken);
            }
        }else {
            accessToken = getAccessToken(appId,appSecret);
            insertToken(accessToken);
        }
        return accessToken;
    }

    /**
     * 插入token
     */
    private void insertToken(String accessToken){
        WxTemplateMessageTokenEntity entity = new WxTemplateMessageTokenEntity();
        entity.setAccess_token(accessToken);
        long time = System.currentTimeMillis();
        entity.setCreate_time(time);
        entity.setOut_time(time + 7000*1000);
        sendByTaskidDao.InsertAccessToken(entity);
    }
}
